import { Promise } from 'es6-promise';
import { Collection , ObjectID } from "mongodb";

import * as utils from '../core/utils';
import { Magics } from "../core/magics";
import { MongoColls } from "../config/mongo";
import { CursorType } from "../core/defines";
import { BaseModel } from "../core/base.model";
import {
    InsertParam ,
    FindOneParam ,
    FindParam ,
    CountParam ,
    UpdateParam ,
} from '../core/params';

export enum MsgType {
    PRIVATE = 1, //私信
    USER    = 2, //个人消息
    SYSTEM  = 3, //系统消息
    PRODUCT = 4, //产品评价
}

export enum MsgStatus {
    CREATE  = 1, //已创建
    REMOVED = 2, //观察者移除
    DELETE  = 3, //已删除
}

export interface MsgInfo {
    _id?: ObjectID,
    type: MsgType,
    status: MsgStatus,
    content : any,
    from: ObjectID,
    to: ObjectID,
    time: Date,
}

export interface MsgFilter {
    page?: number,
    type?: MsgType,
    status?: MsgStatus,
    content?: string,
    from?: ObjectID,
    to?: ObjectID,
    limit?: number,
}

export default class MsgModel extends BaseModel {
    constructor( coll : Collection ) {
        super( coll );
    }

    name() {return 'MsgModel';}

    checkExist(filter: MsgFilter): Promise<any> {
        return this.findOne(new FindOneParam(filter));
    }

    createMsg(msg: MsgInfo): Promise<any> {
        return this.insertOne(new InsertParam<MsgInfo>(msg));
    }

    getMsgList( filter : MsgFilter ) : Promise<any> {
        let {page, type, status, from, to, limit} = filter;
        let match = {};

        if(type){
            match['type'] = type;
        }

        if(status){
            match['status'] = status;
        }else if(from){
            match['from'] = from;
            match['status'] = {'$ne': MsgStatus.DELETE};
        }else if(to){
            match['to'] = to;
            match['status'] = {'$ne': MsgStatus.REMOVED};
        }

        let count;
        return this.count( new CountParam( match ) ).then( ( totalCount ) => {
            count = totalCount;
            let options = new FindParam( match , {} );
            options.sort = {'time': - 1};
            options.skip = page && options.limit * page;
            options.limit = limit;
            return this.find( options );
        } ).then( ( msgs ) => {
            let data = {
                page: page,
                total_count  : count ,
                msgs        : msgs || [],
                total_page   : Math.ceil( count / limit )
            };
            return data;
        } );
    }
}
